package cluster

import (
	"math/rand"
	"sort"
	"sync"
	"time"
)

// 随机获取一个业务服务器
func GetABizServer_random(sjt ServerJobType) (*BizServerData, bool) {
	// 拿到 Sjt 字典
	sjtMap := theBizServerDataGroup().sjtMap

	serverIdSet, ok := sjtMap.Load(sjt)

	if !ok {
		return nil, false
	}

	var serverIdArray []uint32

	serverIdSet.(*sync.Map).Range(func(key interface{}, val interface{}) bool {
		serverIdArray = append(
			serverIdArray, key.(uint32),
		)

		return true
	})

	// 随机一个服务器 Id
	rand.Seed(time.Now().Unix())
	index := rand.Intn(len(serverIdArray))

	// 获取服务器 Id
	serverId := serverIdArray[index]

	return theBizServerDataGroup().getByServerId(serverId)
}

// 根据服务器 Id 获取业务服务器
func GetABizServer_byServerId(serverId uint32) (*BizServerData, bool) {
	// 获取业务服务器数据
	val, ok := theBizServerDataGroup().defaultMap.Load(serverId)

	if !ok {
		return nil, false
	} else {
		return val.(*BizServerData), true
	}
}

// 根据最小负载获取业务服务器
func GetABizServer_byLeastLoad(sjt ServerJobType) (*BizServerData, bool) {
	// 拿到 Sjt 字典
	sjtMap := theBizServerDataGroup().sjtMap

	serverIdSet, ok := sjtMap.Load(sjt)

	if !ok {
		return nil, false
	}

	var bizServerData *BizServerData
	var loadCount uint32

	serverIdSet.(*sync.Map).Range(func(key interface{}, _ interface{}) bool {
		// 获取业务服务器数据
		val, ok := theBizServerDataGroup().defaultMap.Load(key)

		if !ok {
			return true
		}

		currData := val.(*BizServerData)

		if loadCount > currData.LoadCount {
			bizServerData = currData
			loadCount = currData.LoadCount
		}

		return true
	})

	return bizServerData, nil != bizServerData
}

// 根据索引获取业务服务器数据
func GetABizServer_byIndex(sjt ServerJobType, index int) (*BizServerData, bool) {
	// 拿到 Sjt 字典
	sjtMap := theBizServerDataGroup().sjtMap

	serverIdSet, ok := sjtMap.Load(sjt)

	if !ok {
		return nil, false
	}

	var serverIdArray []uint32

	serverIdSet.(*sync.Map).Range(func(key interface{}, val interface{}) bool {
		serverIdArray = append(
			serverIdArray, key.(uint32),
		)

		return true
	})

	if len(serverIdArray) <= 0 {
		// 如果没有一个服务器,
		// 则直接退出!
		return nil, false
	}

	// 排序,
	// 以保证每次取到相同的 serverId
	sort.Slice(
		serverIdArray, func(i, j int) bool {
			return serverIdArray[i] < serverIdArray[j]
		},
	)

	if index < 0 {
		index = -index
	}

	// 获取服务器 Id
	index %= len(serverIdArray)
	serverId := serverIdArray[index]

	// 根据服务器 Id 获取业务服务器数据
	return GetABizServer_byServerId(serverId)
}
